# test = "Hello World"
# print("test: " + test)
# 1 使用numpy构建基本函数
# 1.1 sigmoid function和np.exp()
import math
    # sigmoid:б(x) =1 / (1 + e ^ -x)
def math_sigmoid(x) :
    # math.exp(x) 返回e的x次方
    return 1 / (1 + math.exp(-x))
# print(basic_sigmoid(3))

import numpy as np

x = np.array([1, 2, 3])
# print(np.exp(x))

# np.exp()与math.exp()类似但可以处理向量、矩阵
# math.exp()只能对实数,  但需要处理向量、矩阵所以使用np.exp实现sigmoid
def sigmoid(z) :
    return 1 / (1 + np.exp(-z))
# print(sigmoid(x))

# 1.2 Sigmoid gradient
    # sigmoid(x)` = (e^-x) / (1 + e ^ -x) ^ 2 = 1 / (1 + e ^ -x) * (e ^ -x) / (1 + e ^ -x) = sigmoid(x) * (1 - sigmoid(x))
def sigmoid_derivative(x) :
    s = sigmoid(x)
    return s * (1 - s)
# print("sigmoid_derivative(x) = " + str(sigmoid_derivative(x)))

# 1.3 重塑数组
# np.shape用于获取矩阵的维度
# np.reshape用于重塑矩阵为其他尺寸
def image2vector(image) :
    return image.reshape(image.shape[0] * image.shape[1] * image.shape[2], 1)

image = np.array([[[ 0.67826139,  0.29380381],
        [ 0.90714982,  0.52835647],
        [ 0.4215251 ,  0.45017551]],

       [[ 0.92814219,  0.96677647],
        [ 0.85304703,  0.52351845],
        [ 0.19981397,  0.27417313]],

       [[ 0.60659855,  0.00533165],
        [ 0.10820313,  0.49978937],
        [ 0.34144279,  0.94630077]]])

# print ("image2vector(image) = " + str(image2vector(image)))

# 1.4 行标准化
# 行标准化: 将x改变为x / ||x||
# np.linalg.norm(x, ord, axis, keepdims) 计算x的模
    # ord: 范数类型
        # 1: L1范数(曼哈顿距离) : 所有元素的绝对值之和
        # 2: L2范数(欧几里得距离) : 向量元素平方和的平方根
        # 3: 无穷大范数 : 向量中绝对值最大的元素
    # axis: 行还是列
        # 0: 列
        # 1: 行
    # keepdims:
        # true: 保持原型装
        # false: 不保持
def normalizeRows(x) :
    x_norm = np.linalg.norm(x, axis = 1, keepdims = True)
    x = x / x_norm
    return x
x = np.array([
    [0, 3, 4],
    [1, 6, 4]])
# print("normalizeRows(x) = " + str(normalizeRows(x)))

# 1.5 广播和softmax函数
    # 广播: 矩阵会变成自己复制以适应矩阵运算
def softmax(x):
    x_exp = np.exp(x)
    # print(str(x_exp))
    x_sum = np.sum(x_exp, axis=1, keepdims=True)
    # print(str(x_sum))
    return x_exp / x_sum
x = np.array([
    [9, 2, 5, 0, 0],
    [7, 5, 0, 0 ,0]])
# print("softmax(x) = " + str(softmax(x)))

# 2. 向量化
# 2.1. 实现L1和L2损失函数
    # L1损失函数: L1(^y, y) = ∑|^y(i) - y(i)|
def L1(yhat, y) :
    return np.sum(np.abs(y - yhat))
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])
# print("L1 = " + str(L1(yhat,y)))

    # L2损失函数: L2(^y, y) = ∑(^y(i) - y(i)) ^ 2
def L2(yhat, y) :
    return np.dot((y - yhat), (y - yhat).T)
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y = np.array([1, 0, 0, 1, 1])
# print("L2 = " + str(L2(yhat,y)))